<template>
  <div>
    <el-dialog
      :title="dialogTitle"
      :visible="addDialogDepart"
      width="30%"
      @close="closeDialog"
    >
      <!-- :model  :rules  prop  v-model -->
      <el-form ref="form" :rules="rules" :model="form" label-width="120px">
        <el-form-item label="部门名称" prop="name">
          <el-input v-model="form.name" />
        </el-form-item>
        <el-form-item label="部门编码" prop="code">
          <el-input v-model="form.code" />
        </el-form-item>
        <el-form-item label="部门负责人" prop="manager">
          <el-select v-model="form.manager" placeholder="请选择部门负责人">
            <el-option
              v-for="item in leaderList"
              :key="item.id"
              :label="item.username"
              :value="item.username"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="部门介绍" prop="introduce">
          <el-input v-model="form.introduce" type="textarea" />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="closeDialog">取 消</el-button>
          <el-button type="primary" @click="addDepartmentFn"> 确 定 </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>
<script>
import {
  getLeaderListApi,
  addDepartmentApi,
  getDepartmentApi,
  editDepartmentApi
} from '@/api/departments'
export default {
  props: {
    addDialogDepart: {
      type: Boolean,
      default: false
    },
    // eslint-disable-next-line vue/require-default-prop
    nodeData: {
      type: Object
    },
    // eslint-disable-next-line vue/require-default-prop
    departsList: {
      type: Array
    }
  },
  data() {
    // rule 校验相关的说明，比如校验是那个字段（没啥用）
    // value 校验表单元素的值
    // callback 回调函数，无论校验成功与否，必须调用callback方法
    const validateName = (rule, value, callback) => {
      let arr = []
      if (this.form.id) {
        // 当前输入框的值 等于 当前编辑的部门name，直接通过校验
        if (this.nodeData.name === value) {
          callback()
          return
        }
        // 编辑状态，应该要和自身的兄弟做比对
        arr = this.departsList.filter((item) => item.pid === this.nodeData.pid)
      } else {
        // 非编辑状态，应该是和自身的儿子做比对
        // 1. value 根据老父亲 nodeData.id 来找所有儿子（item.pid）, 过滤出所有兄弟
        arr = this.departsList.filter((item) => item.pid === this.nodeData.id)
      }
      // 同级部门不能有重复的部门名字
      // 2. 只要 value 和 arr 中任意一个部门的 name 相等，就不通过校验
      // some知识点
      // 点1:如果有一个元素满足条件，则表达式返回true , 剩余的元素不会再执行遍历。
      // 点2:如果没有满足条件的元素，则返回false。
      const bool = arr.some((item) => item.name === value)
      // 3. 判断，是否重复
      bool ? callback(new Error('出现了重名的部门')) : callback()
    }

    const validateCode = (rule, value, callback) => {
      // 编辑状态code可以和原来一样，但是不能和别的部门编码一样
      if (this.form.id && this.nodeData.code === value) {
        callback()
        return
      } else {
        // 所有部门都不该有重复的部门编码，所以应遍历所有的数据
        const bool = this.departsList.some((item) => item.code === value)
        bool ? callback(new Error('出现了重复的部门编码')) : callback()
      }
    }
    return {
      form: {
        name: '',
        code: '',
        introduce: '',
        manager: '',
        pid: ''
      },
      rules: {
        name: [
          {
            required: true,
            message: '请输入部门名称',
            trigger: ['blur', 'change']
          },
          {
            min: 1,
            max: 10,
            message: '部门名称1到10个字符',
            trigger: ['blur', 'change']
          },
          { validator: validateName, trigger: ['blur', 'change'] }
        ],
        code: [
          {
            required: true,
            message: '请输入部门编码',
            trigger: ['blur', 'change']
          },
          {
            min: 1,
            max: 10,
            message: '部门编码1到10个字符',
            trigger: ['blur', 'change']
          },
          { validator: validateCode, trigger: ['blur', 'change'] }
        ],
        manager: [
          {
            required: true,
            message: '请选择部门负责人',
            trigger: ['blur', 'change']
          }
        ],
        introduce: [
          {
            required: true,
            message: '请输入部门介绍',
            trigger: ['blur', 'change']
          },
          {
            min: 1,
            max: 300,
            message: '部门介绍1到300个字符',
            trigger: ['blur', 'change']
          }
        ]
      },
      leaderList: []
      // dialogTitle: ''
    }
  },
  computed: {
    dialogTitle() {
      return this.form.id ? '编辑部门' : '添加子部门'
    }
  },
  async created() {},
  methods: {
    closeDialog() {
      // 1、关闭弹层
      // this.$emit('closeDialog')
      // update: 固定的写法，后面跟的是要修改的props变量
      // $emit 第二个参数 跟的是要修改的值
      this.$emit('update:addDialogDepart', false)
      // 2、清空表单的值
      this.form = {
        name: '',
        code: '',
        manager: '',
        introduce: '',
        pid: ''
      }
      // 3、resetFields 将所有字段值重置为初始值并移除校验结果
      this.$refs.form.resetFields()
    },
    async getLeaderList() {
      const { data } = await getLeaderListApi()
      this.leaderList = data
    },
    addDepartmentFn() {
      this.$refs.form.validate(async (valid, val) => {
        if (!valid) return
        // 点击了确定，有可能是编辑，也有可以是添加
        // 有id那就是编辑
        // 没id是添加
        if (this.form.id) {
          await editDepartmentApi(this.form)
        } else {
          // 拼接父级id
          this.form.pid = this.nodeData.id
          await addDepartmentApi(this.form)
        }
        // 发送成功后关闭弹层
        // 不管添加还是编辑都要重新渲染部门列表和关闭弹层
        this.$emit('getDepart')
        this.closeDialog()
      })
    },

    // 获取部门详情
    async getDepartment() {
      const id = this.nodeData.id
      const { data } = await getDepartmentApi(id)
      // 数据回显
      this.form = data
    }
  }
}
</script>
<style scoped></style>
